package pwr.online.cow;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.LinkedList;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

import pwr.online.cow.model.BoardUpdateListener;
import pwr.online.cow.model.Position;
import pwr.online.cow.model.Position2D;

@SuppressWarnings("serial")
public class Board2DView extends JPanel implements BoardUpdateListener,
                                                   BoardControllerListener,
                                                   MouseListener {

	static private int CELL_SIZE = 50;
	static public int CELLS_HORIZONTAL = 15;
	static public int CELLS_VERTICAL = 15;
	static private Image mCowImage;
	static {
		URL url = Board2DView.class.getResource("/larry.png");
    	mCowImage = new ImageIcon(url).getImage();
	}
	
	private Position2D mCowPosition;
	private LinkedList<Position2D> mDrawingPos;
	private int mHistoryLimit;
	private LinkedList<CowPositionUpdateListener> mCowUpdateListeners;
	
	public Board2DView() {
		mHistoryLimit = -1;
		mDrawingPos = new LinkedList<Position2D>();
		mCowPosition = new Position2D(0, 0);
		mCowUpdateListeners = new LinkedList<CowPositionUpdateListener>();
		addMouseListener(this);
	}
	
	@Override
	public Dimension getPreferredSize() {
		return new Dimension(CELLS_HORIZONTAL * CELL_SIZE, CELLS_VERTICAL * CELL_SIZE);
	}
	
	@Override
	public Dimension getMinimumSize() {
		return getPreferredSize();
	}
	
	@Override
	public Dimension getMaximumSize() {
		return getPreferredSize();
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		
		Dimension size = getMaximumSize();
		
		g.setColor(Color.LIGHT_GRAY);
		for (int i = 0; i < getHistoryLimit()-1; ++i) {
			Position2D p = mDrawingPos.get(i);
			g.fillRect(p.getX() * CELL_SIZE,
					   p.getY() * CELL_SIZE,
					   CELL_SIZE,
					   CELL_SIZE);
		}
		
		g.setColor(Color.BLACK);
		for (int y = 0; y <= size.height; y += CELL_SIZE)
			g.drawLine(0, y, size.width, y);

		for (int x = 0; x <= size.width; x += CELL_SIZE)
			g.drawLine(x, 0, x, size.height);

		g.setColor(Color.BLUE);
		for (int i = 0; i < getHistoryLimit()-2; ++i) {
			Position2D p1 = mDrawingPos.get(i);
			Position2D p2 = mDrawingPos.get(i+1);

			g.drawLine(p1.getX() * CELL_SIZE + CELL_SIZE/2,
					   p1.getY() * CELL_SIZE + CELL_SIZE/2,
					   p2.getX() * CELL_SIZE + CELL_SIZE/2,
					   p2.getY() * CELL_SIZE + CELL_SIZE/2);
		}
		
		if (mCowImage != null)
			g.drawImage(mCowImage,
						mCowPosition.getX() * CELL_SIZE,
					    mCowPosition.getY() * CELL_SIZE,
					    null);
		g.setColor(Color.BLACK);
		g.drawRect(0, 0, size.width-1, size.height-1);
	}
	
	@Override
	public void OnBoardHistoryAdded(Position addedPosition) {
		mDrawingPos.add((Position2D) addedPosition);
		repaint();
	}

	@Override
	public void OnBoardHistoryCleared() {
	}
	
	private int getHistoryLimit() {
		return mHistoryLimit == -1 ? mDrawingPos.size() : mHistoryLimit;
	}
	
	public void setCowPosition(Position cowPosition) {
		mCowPosition = (Position2D) cowPosition;
		for (CowPositionUpdateListener l : mCowUpdateListeners)
			l.CowPositionUpdated(cowPosition);
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		setCowPosition(new Position2D(e.getX()/CELL_SIZE, e.getY()/CELL_SIZE));
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {}
	@Override
	public void mouseExited(MouseEvent arg0) {}
	@Override
	public void mousePressed(MouseEvent arg0) {}
	@Override
	public void mouseReleased(MouseEvent arg0) {}

	public void AddCowPositionUpdateListener(CowPositionUpdateListener listener) {
		mCowUpdateListeners.add(listener);
	}
	
	@Override
	public void HistoryViewChanged(int newValue) {
		mHistoryLimit = newValue;
		repaint();
	} 

	@Override
	public void RestartAlgorithm() {
		mDrawingPos.clear();
		repaint();
	}

	@Override
	public void NewStartDirection(int x, int y) {}
}
